﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

using BizElements.TemplateEngine;

namespace BizElements.Generator
{
    public partial class TemplateCollectionCtl : UserControl
    {
        List<TemplateCtl> templateControls = new List<TemplateCtl>();

        public TemplateCollectionCtl()
        {
            InitializeComponent();
            this.templateControls.Add(this.uiTemplate0);
        }                

        #region Properties end events.

        public string DefaultTemplateFileName
        {
            get 
            {
                if (this.templateControls.Count > 0)
                    return this.templateControls[0].DefaultTemplateFileName;
                else
                    return null;
            }
            set 
            { 
                if (this.templateControls.Count > 0)
                    this.templateControls[0].DefaultTemplateFileName = value; 
            }
        }

        IVariableValueBus variableBus;

        [Browsable(false)]
        public IVariableValueBus VariableBus
        {
            get { return this.variableBus; }
            set 
            { 
                this.variableBus = value;
                foreach (TemplateCtl ucTemplate in this.templateControls)
                    ucTemplate.VariableBus = value;
            }
        }

        [Browsable(false)]
        public ITemplate[] Templates
        {
            get
            {
                ITemplate[] templates = new ITemplate[this.templateControls.Count];
                for (int i = 0; i < templates.Length; i++)
                    templates[i] = this.templateControls[i].Template;

                return templates;
            }
        }

        string fileFilter;

        public string FileFilter
        {
            get { return this.fileFilter; }
            set
            {
                this.fileFilter = value;
                this.uiTemplate0.FileFilter = value;
            }
        }

        #endregion

        #region Add/Remove template.

        private void uiAddTemplate_Click(object sender, EventArgs e)
        {
            AddTemplate();
            this.AutoScrollPosition = new Point(0, this.VerticalScroll.Maximum);
        }

        private void AddTemplate()
        {
            TemplateCtl newTemplateCtl = CreateTemplateControl();
            AttachTemplateControl(newTemplateCtl);
            EnableChangeTemplateOnlyForBottomControl();
        }

        private TemplateCtl CreateTemplateControl()
        {
            TemplateCtl newTemplateCtl = new TemplateCtl();
            int nextIdx = this.templateControls.Count;
            newTemplateCtl.Name = "uiTemplate" + nextIdx.ToString();

            newTemplateCtl.DefaultTemplateFileName = this.DefaultTemplateFileName;
            newTemplateCtl.VariableBus = this.VariableBus;
            newTemplateCtl.FileFilter = this.FileFilter;
            newTemplateCtl.Width = this.Width;
            newTemplateCtl.Anchor = AnchorStyles.Left | AnchorStyles.Right;
            newTemplateCtl.BorderStyle = BorderStyle.None;

            return newTemplateCtl;
        }

        private void AttachTemplateControl(TemplateCtl newTemplateCtl)
        {                        
            this.templateControls.Add(newTemplateCtl);
            this.uiTable.Controls.Add(newTemplateCtl);
        }

        private void DettachTemplateControl(TemplateCtl ucBottom)
        {
            this.templateControls.Remove(ucBottom);
            this.uiTable.Controls.Remove(ucBottom);
        }

        private void uiRemoveBottomTemplate_Click(object sender, EventArgs e)
        {
            if (this.templateControls.Count == 1)
            {
                MessageBox.Show(Messages.TemplateCollectionCtl_AtLeastOneTemplateRequired, Messages.TemplateCollectionCtl_RemoveBottomTemplate, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            RemoveBottomTemplateControl(true);
        }

        private void RemoveBottomTemplateControl(bool askUser)
        {
            TemplateCtl ucBottom = this.templateControls[this.templateControls.Count - 1];
            string caption = (ucBottom.Template != null)
                ? string.Format(Messages.TemplateCollectionCtl_RemoveTemplateFormat, ucBottom.Template.Header.Title)
                : Messages.TemplateCollectionCtl_RemoveBottomTemplate;

            if (askUser)
            {
                var answer = MessageBox.Show(Messages.TemplateCollectionCtl_AreYouSure, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if ((answer == DialogResult.Yes))
                {
                    DettachTemplateControl(ucBottom);
                    EnableChangeTemplateOnlyForBottomControl();
                }
            }
            else
            {
                DettachTemplateControl(ucBottom);
                EnableChangeTemplateOnlyForBottomControl();
            }
        }        

        private void EnableChangeTemplateOnlyForBottomControl()
        {
            for (int i = 0; i < this.templateControls.Count; i++)
            {
                bool isLast = (i == this.templateControls.Count - 1);
                this.templateControls[i].ChangeTemplateEnabled = isLast;
            }
        }

        #endregion

        #region Project Settings.

        public void ReadProjectSettings(string collectionKeyPrefix, BizElementsSettings projectSettings)
        {
            string cfgTemplateCount = projectSettings[collectionKeyPrefix + "_TemplateCount"] ?? "1";
            EnsureSpecifiedNumberOfTemplateControl(int.Parse(cfgTemplateCount));

            for (int i = 0; i < this.templateControls.Count; i++)
            {
                string currTemplateKeyPrefix = collectionKeyPrefix + "_" + i.ToString("D2");
                this.templateControls[i].ReadSettings(currTemplateKeyPrefix, projectSettings);
            }
        }

        private void EnsureSpecifiedNumberOfTemplateControl(int requestedCount)
        {
            // At least one control must exist.
            if (requestedCount < 1)
                requestedCount = 1;

            if (this.templateControls.Count < requestedCount)
            {
                while (this.templateControls.Count < requestedCount)
                    AddTemplate();
            }
            else if (this.templateControls.Count > requestedCount)
            {
                while (this.templateControls.Count > requestedCount)
                    RemoveBottomTemplateControl(/*no message boxes*/ false);
            }
        }

        public void WriteProjectSettings(string collectionKeyPrefix, BizElementsSettings projectSettings)
        {
            projectSettings[collectionKeyPrefix + "_TemplateCount"] = this.templateControls.Count.ToString();
            for (int i = 0; i < this.templateControls.Count; i++)
            {
                string currTemplateKeyPrefix = collectionKeyPrefix + "_" + i.ToString("D2");
                this.templateControls[i].WriteSettings(currTemplateKeyPrefix, projectSettings);
            }
        }

        #endregion

        public IList<TemplateComponentVariableDefinition> CreateComponentVariableDefinitionList()
        {
            List<TemplateComponentVariableDefinition> allVariables = new List<TemplateComponentVariableDefinition>();
            foreach (Template template in this.Templates)
            {
                foreach (TemplateComponentVariableDefinition var in template.ComponentVariableDefinitions)
                {
                    bool alreadyAdded = allVariables.Exists((v) => (v.Name == var.Name));
                    if (!alreadyAdded)
                        allVariables.Add(var);
                }
            }

            return allVariables;
        }
    }
}
